#include "LiteMiddle.h"

#define LITECMD_UARTRX      g_tUart4        //  cmd串口  

#define LITECMD_BUFSIZE      64             //  Buf最大字节数

LiteCmd_T g_tLiteCmd;                       //  LiteCmd操作句柄
static u8  s_ucaBufCmd[LITECMD_BUFSIZE];    //  命令缓存区 
static u8  s_ucaBufTx[LITECMD_BUFSIZE];     //  发送缓存区 

static BUFFER_T BufTx = {s_ucaBufTx,LITECMD_BUFSIZE,0};
static BUFFER_T BufCmd  = {s_ucaBufCmd,LITECMD_BUFSIZE,0};
/*
*********************************************************************************************************
* 函 数 名:   LITE_CMD_Init
* 功能说明:   初始化LiteCmd中间件
* 形    参:   
* 返 回 值:   无
*********************************************************************************************************
*/
void LITE_CMD_Init(void)
{
  //  step1：初始化对应的串口设备驱动
//  BSP_UART_Init();  
  
  //  step2：参数初始化
  g_tLiteCmd.FsmState     = CMD_STATE_INIT;                      //Miaozi：初始化状态
  g_tLiteCmd.tpUart       = &LITECMD_UARTRX;                     //  载入串口4驱动
  
  g_tLiteCmd.ucCmdAcq     = 0;                                   //  缺省配置
  g_tLiteCmd.tpTxBuf      = &BufTx;                              //  发送缓存
  g_tLiteCmd.tpRxBuf      = g_tLiteCmd.tpUart->tpRxBuf;          //  接收缓存
  g_tLiteCmd.tpCmdBuf     = &BufCmd;                             //  命令缓存
 
  g_tLiteCmd.usCmdPop     = 0;                                   //  命令出队索引
  g_tLiteCmd.usRxBufLen   = 0;                                   //  接收到的数据长度

  return;
}

/*
*********************************************************************************************************
* 函 数 名:   LITE_CMD_RunCommand
* 功能说明:   LiteCmd运行命令 - 运行配对成功的指令
* 形    参:   无
* 返 回 值:   1：执行成功；0：执行失败
*********************************************************************************************************
*/
u8 LITE_CMD_RunCommand(void)
{
  //  step1：找到参数位置
  g_tLiteCmd.usCmdPop += strlen((char *)g_tLiteCmd.tCmd.ucpCmd);  // 跳过命令头
  while((g_tLiteCmd.tpCmdBuf->data[g_tLiteCmd.usCmdPop]==' ')||(g_tLiteCmd.tpCmdBuf->data[g_tLiteCmd.usCmdPop]=='\t'))
  {
    g_tLiteCmd.usCmdPop++;  //  不必担心越界，末尾有哨兵'\0'  
  }
  
  u8 *ucpLine =  g_tLiteCmd.tpCmdBuf->data+g_tLiteCmd.usCmdPop;  //  参数串

  //  执行函数指针并返回结果
  return g_tLiteCmd.tCmd.fpCmdfunc(ucpLine);
}
/*
*********************************************************************************************************
* 函 数 名:   LITE_CMD_Parese
* 功能说明:   LiteCmd任务 —— 执行数据解析，在命令末尾补\0(哨兵)
* 形    参:   
* 返 回 值:   1：成功解析出CMD子串 0：未解析出CMD子串
*********************************************************************************************************
*/
u8 LITE_CMD_Parese(void)
{
  u8 ch;
  u16 usPopPos = 0;             //  接收缓存队头索引
  
  while(usPopPos != g_tLiteCmd.usRxBufLen)  //  数据未完全处理
  {
    ch = g_tLiteCmd.tpRxBuf->data[usPopPos++];  //  得到接收缓存最先入队的字符

    switch(ch)
    {
      case 0x1b:  // ESC ，遇到ESC，回显$
        g_tLiteCmd.ucCmdAcq = 1;              //  进入命令模式
        BUF_Clear(g_tLiteCmd.tpCmdBuf);       //  清空命令缓存
        BUF_Write(g_tLiteCmd.tpTxBuf,"$",1);  //  回显$，推入发送缓存
        break;
      case 0x0a:  // LF
      case 0x0d:  // CR
          if(g_tLiteCmd.ucCmdAcq) 
            { 
              BUF_Write(g_tLiteCmd.tpTxBuf,"\r\n",sizeof("\r\n")); //  推入发送缓存，回显$
              BUF_Write(g_tLiteCmd.tpCmdBuf,"\0",sizeof("\0"));    //  推入命令缓存区，'\0'是命令结束符（哨兵）
              g_tLiteCmd.ucCmdAcq = 0;                  //  退出命令模式
              return 1;
            }
        break;
      case 0x08:  // BS ，遇到退格 按三个字符处理：退格、空格、退格
          if(g_tLiteCmd.ucCmdAcq && g_tLiteCmd.tpCmdBuf->length>0) 
          {
            u8 TmpStr[]={ch,' ',ch};
            BUF_Write(g_tLiteCmd.tpTxBuf,TmpStr,3);  //  推入发送缓存
            g_tLiteCmd.tpCmdBuf->length--;           //  命令缓存区删去一个字符
          }
        break;
      default :
        if(g_tLiteCmd.ucCmdAcq)       //  命令模式:回显&缓存
        {
          BUF_Write(g_tLiteCmd.tpTxBuf,&ch,1);       //  推入发送缓存
          BUF_Write(g_tLiteCmd.tpCmdBuf,&ch,1);      //  推入命令缓存
        }
        break;
    }
  }
  
  return 0;
}

/*
*********************************************************************************************************
* 函 数 名:   LITE_CMD_Match
* 功能说明:   LiteCmd配对 - 匹配CMD是否存在及参数子串归位
* 形    参:   CMDTBL_T *tpCmd ：一个命令盒子
* 返 回 值:   1：匹配成功；0：匹配失败
*********************************************************************************************************
*/
u8 LITE_CMD_Match(const CMDTBL_T *tpCmd)
{
  //  step1：保护
  if( tpCmd==NULL ) return 0;
  
  g_tLiteCmd.usCmdPop = 0;   //  队头索引复位，命令缓存

  //  找到第一个非' ' '\t'的字符，索引为g_tLiteCmd.usCmdPop
  while((g_tLiteCmd.tpCmdBuf->data[g_tLiteCmd.usCmdPop]==' ')||(g_tLiteCmd.tpCmdBuf->data[g_tLiteCmd.usCmdPop]=='\t'))
  {
    g_tLiteCmd.usCmdPop++;  //  不必担心越界，末尾有哨兵'\0'  
  }
  
  if(g_tLiteCmd.tpCmdBuf->data[g_tLiteCmd.usCmdPop] != '\0')   //  未到达哨兵位置
  {
    while(tpCmd->ucpCmd)  //  命令盒子中是否存在匹配的命令？
    {
      if (!memcmp(tpCmd->ucpCmd,g_tLiteCmd.tpCmdBuf->data+g_tLiteCmd.usCmdPop, strlen((char *)tpCmd->ucpCmd)))  
      {  //  找到匹配的命令
        
        g_tLiteCmd.tCmd.ucpCmd    = (u8 *)tpCmd->ucpCmd;   //  命令字符串拷贝
        g_tLiteCmd.tCmd.fpCmdfunc = tpCmd->fpCmdfunc;      //  函数指针拷贝
        return 1;
      }
      tpCmd++;          //  此盒子最后一条的tpCmd->ucpCmd为0，故可退出循环。
    }   //  未找到匹配的命令
  }

  u8 TemStr[]="invalid command!\r\n"; 
  BUF_Write(g_tLiteCmd.tpTxBuf,TemStr,strlen((char *)TemStr));  //  推入发送缓存
  
  return 0;
}

/*
*********************************************************************************************************
* 函 数 名:   LITE_CMD_Capture
* 功能说明:   LiteCmd捕获处理 - 响应串口并做数据预处理
* 形    参:   
* 返 回 值:   1：捕获成功；0：未检测到串口数据
*********************************************************************************************************
*/
u8 LITE_CMD_Capture(void)
{
  // step1：保护
  if(IS_FLAG_SET(g_tLiteCmd.tpUart->state,UART_RX_DONE)==0) return 0;                      //  当前串口没有收到数据

  g_tLiteCmd.usRxBufLen         = g_tLiteCmd.tpUart->tpRxBuf->length;      //  得到待处理数据的长度
  return 1;
}

//  设置发送状态机阶段
void LITE_CMD_SetState(CMD_STATE_E Index)
{
  g_tLiteCmd.FsmState=Index;
  return  ;
}

 /***************************** LiteBsp by Miaozi (END OF FILE) *********************************/
